/**
 * @file g711.c  G.711 test vectors
 *
 * Copyright (C) 2010 Creytiv.com
 */
#include <string.h>
#include <re.h>
#include <rem_g711.h>
#include "test.h"


#define DEBUG_MODULE "test_g711"
#define DEBUG_LEVEL 5
#include <re_dbg.h>


/* G.711 reference tables - copied from re/src/g711/g711.c */


static const signed short _st_alaw2linear16[256] = {
	-5504,   -5248,   -6016,   -5760,   -4480,   -4224,   -4992,
	-4736,   -7552,   -7296,   -8064,   -7808,   -6528,   -6272,
	-7040,   -6784,   -2752,   -2624,   -3008,   -2880,   -2240,
	-2112,   -2496,   -2368,   -3776,   -3648,   -4032,   -3904,
	-3264,   -3136,   -3520,   -3392,  -22016,  -20992,  -24064,
	-23040,  -17920,  -16896,  -19968,  -18944,  -30208,  -29184,
	-32256,  -31232,  -26112,  -25088,  -28160,  -27136,  -11008,
	-10496,  -12032,  -11520,   -8960,   -8448,   -9984,   -9472,
	-15104,  -14592,  -16128,  -15616,  -13056,  -12544,  -14080,
	-13568,    -344,    -328,    -376,    -360,    -280,    -264,
	-312,    -296,    -472,    -456,    -504,    -488,    -408,
	-392,    -440,    -424,     -88,     -72,    -120,    -104,
	-24,      -8,     -56,     -40,    -216,    -200,    -248,
	-232,    -152,    -136,    -184,    -168,   -1376,   -1312,
	-1504,   -1440,   -1120,   -1056,   -1248,   -1184,   -1888,
	-1824,   -2016,   -1952,   -1632,   -1568,   -1760,   -1696,
	-688,    -656,    -752,    -720,    -560,    -528,    -624,
	-592,    -944,    -912,   -1008,    -976,    -816,    -784,
	-880,    -848,    5504,    5248,    6016,    5760,    4480,
	4224,    4992,    4736,    7552,    7296,    8064,    7808,
	6528,    6272,    7040,    6784,    2752,    2624,    3008,
	2880,    2240,    2112,    2496,    2368,    3776,    3648,
	4032,    3904,    3264,    3136,    3520,    3392,   22016,
	20992,   24064,   23040,   17920,   16896,   19968,   18944,
	30208,   29184,   32256,   31232,   26112,   25088,   28160,
	27136,   11008,   10496,   12032,   11520,    8960,    8448,
	9984,    9472,   15104,   14592,   16128,   15616,   13056,
	12544,   14080,   13568,     344,     328,     376,     360,
	280,     264,     312,     296,     472,     456,     504,
	488,     408,     392,     440,     424,      88,      72,
	120,     104,      24,       8,      56,      40,     216,
	200,     248,     232,     152,     136,     184,     168,
	1376,    1312,    1504,    1440,    1120,    1056,    1248,
	1184,    1888,    1824,    2016,    1952,    1632,    1568,
	1760,    1696,     688,     656,     752,     720,     560,
	528,     624,     592,     944,     912,    1008,     976,
	816,     784,     880,     848
};


static const signed short _st_ulaw2linear16[256] = {
	-32124,  -31100,  -30076,  -29052,  -28028,  -27004,  -25980,
	-24956,  -23932,  -22908,  -21884,  -20860,  -19836,  -18812,
	-17788,  -16764,  -15996,  -15484,  -14972,  -14460,  -13948,
	-13436,  -12924,  -12412,  -11900,  -11388,  -10876,  -10364,
	-9852,   -9340,   -8828,   -8316,   -7932,   -7676,   -7420,
	-7164,   -6908,   -6652,   -6396,   -6140,   -5884,   -5628,
	-5372,   -5116,   -4860,   -4604,   -4348,   -4092,   -3900,
	-3772,   -3644,   -3516,   -3388,   -3260,   -3132,   -3004,
	-2876,   -2748,   -2620,   -2492,   -2364,   -2236,   -2108,
	-1980,   -1884,   -1820,   -1756,   -1692,   -1628,   -1564,
	-1500,   -1436,   -1372,   -1308,   -1244,   -1180,   -1116,
	-1052,    -988,    -924,    -876,    -844,    -812,    -780,
	-748,    -716,    -684,    -652,    -620,    -588,    -556,
	-524,    -492,    -460,    -428,    -396,    -372,    -356,
	-340,    -324,    -308,    -292,    -276,    -260,    -244,
	-228,    -212,    -196,    -180,    -164,    -148,    -132,
	-120,    -112,    -104,     -96,     -88,     -80,     -72,
	-64,     -56,     -48,     -40,     -32,     -24,     -16,
	-8,       -2,   32124,   31100,   30076,   29052,   28028,
	27004,   25980,   24956,   23932,   22908,   21884,   20860,
	19836,   18812,   17788,   16764,   15996,   15484,   14972,
	14460,   13948,   13436,   12924,   12412,   11900,   11388,
	10876,   10364,    9852,    9340,    8828,    8316,    7932,
	7676,    7420,    7164,    6908,    6652,    6396,    6140,
	5884,    5628,    5372,    5116,    4860,    4604,    4348,
	4092,    3900,    3772,    3644,    3516,    3388,    3260,
	3132,    3004,    2876,    2748,    2620,    2492,    2364,
	2236,    2108,    1980,    1884,    1820,    1756,    1692,
	1628,    1564,    1500,    1436,    1372,    1308,    1244,
	1180,    1116,    1052,     988,     924,     876,     844,
	812,     780,     748,     716,     684,     652,     620,
	588,     556,     524,     492,     460,     428,     396,
	372,     356,     340,     324,     308,     292,     276,
	260,     244,     228,     212,     196,     180,     164,
	148,     132,     120,     112,     104,      96,      88,
	80,      72,      64,      56,      48,      40,      32,
	24,      16,       8,       2
};


int test_g711_alaw(void)
{
	uint32_t i;
	uint8_t val;
	int n = 0;
	int err = 0;

	val = g711_pcm2alaw(-32768);
	TEST_EQUALS(42, val);

	for (i=0; i<256; i++) {
		uint8_t alaw = i, alaw2;
		int16_t pcm_ref = _st_alaw2linear16[alaw];
		int16_t pcm = g711_alaw2pcm(alaw);

		if (pcm_ref != pcm) {
			DEBUG_INFO("alaw: %u: bogus sample: ref=%d gen=%d\n",
				   i, pcm_ref, pcm);
			++n;
		}

		alaw2 = g711_pcm2alaw(pcm);
		if (alaw2 != alaw) {
			DEBUG_INFO("alaw: %u: bogus alaw %d != %d\n",
				   i, alaw, alaw2);
			++n;
		}
	}

	if (n) {
		DEBUG_WARNING("alaw: error samples: %d\n", n);
	}

out:
	return n ? EINVAL : err;
}


int test_g711_ulaw(void)
{
	uint32_t i;
	uint8_t val;
	int n = 0;
	int err = 0;

	val = g711_pcm2ulaw(-32768);
	TEST_EQUALS(0, val);

	for (i=0; i<256; i++) {
		uint8_t ulaw = i, ulaw2;
		int16_t pcm_ref = _st_ulaw2linear16[ulaw];
		int16_t pcm = g711_ulaw2pcm(ulaw);

		if (pcm != pcm_ref) {
			DEBUG_INFO("ulaw: %u: bogus sample ref=%d gen=%d\n",
				   i, pcm_ref, pcm);
			++n;
		}

		ulaw2 = g711_pcm2ulaw(pcm_ref);
		if (ulaw2 != ulaw) {
			DEBUG_INFO("ulaw: %u: bogus ulaw %d != %d\n",
				   i, ulaw, ulaw2);
			++n;
		}
	}

	if (n) {
		DEBUG_WARNING("ulaw: error samples: %d\n", n);
	}
out:
	return n ? EINVAL : err;
}
